package cn.craftyun.yunexam.controller;

import cn.craftyun.yunexam.entity.*;
import cn.craftyun.yunexam.request.*;
import cn.craftyun.yunexam.service.*;
import cn.craftyun.yunexam.vo.ResultEntity;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Log4j2
@RequestMapping("/admin")
public class AdminController {
    @Resource
    private ExamService examService;
    @Resource
    private UserService userService;
    @Resource
    private PaperService paperService;
    @Resource
    private ExamStatusService examStatusService;
    @Resource
    private ExamAnswerService examAnswerService;
    @Resource
    private QuestionService questionService;
    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private AdminUserService adminUserService;

    /**
     * 获取系统基础信息
     *
     * @return 结果实体类
     */
    @GetMapping("/getSystemInfo")
    public ResultEntity getSystemInfo() {
        Map<String, String> resultMap = new HashMap<>();

        // 构造条件
        Wrapper<ExamStatus> wrapper = new QueryWrapper<ExamStatus>().eq("status", 0);

        // 构造返回的map
        resultMap.put("total_user", String.valueOf(userService.count()));
        resultMap.put("on_exam_num", String.valueOf(examStatusService.count(wrapper)));
        resultMap.put("paper_num", String.valueOf(paperService.count()));
        resultMap.put("total_exam", String.valueOf(examService.count()));

        return ResultEntity.success("获取系统信息成功", resultMap);
    }

    /**
     * 获取正在进行的5个考试
     *
     * @return 结果实体类
     */
    @GetMapping("/getActiveExam")
    public ResultEntity getActiveExam() {
        return ResultEntity.success("获取安排考试成功", examService.getActiveExam(5));
    }

    /**
     * 获得所有的考试安排(分页)
     *
     * @param current 当前页数
     * @return 分页对象
     */
    @GetMapping("/getAllExam")
    public ResultEntity getAllExam(@RequestParam Integer current) {
        return ResultEntity.success("获取成功", examService.findAllExam(new Page<>(current, 10)));
    }

    /**
     * 获取考试信息
     *
     * @param examIdRequest 考试ID
     * @return 结果实体类
     */
    @PostMapping("/getExam")
    public ResultEntity getExam(@RequestBody @Valid ExamIdRequest examIdRequest) {
        Exam exam = examService.getById(examIdRequest.getExamId());
        if (exam == null) {
            return ResultEntity.error("考试不存在", null);
        }
        return ResultEntity.success("获取考试成功", exam);
    }

    /**
     * 删除考试(级联删除)
     *
     * @param examIdRequest 考试ID对象
     * @return 结果实体类
     */
    @PostMapping("/deleteExam")
    @Transactional
    public ResultEntity deleteExam(@RequestBody @Valid ExamIdRequest examIdRequest) {
        Exam exam = examService.getById(examIdRequest.getExamId());
        if (exam == null) {
            return ResultEntity.error("考试不存在", null);
        }
        // 删除对应的考试
        Assert.isTrue(examService.removeById(examIdRequest.getExamId()), "删除考试失败");
        // 删除对应的考试状态
        examStatusService.removeByExamId(examIdRequest.getExamId());
        // 删除对应的用户考试答案
        examAnswerService.removeByExamId(examIdRequest.getExamId());
        return ResultEntity.success("删除考试成功", null);
    }

    /**
     * 结束考试
     *
     * @param examIdRequest 考试ID对象
     * @return 结果实体类
     */
    @PostMapping("/endExam")
    public ResultEntity endExam(@RequestBody @Valid ExamIdRequest examIdRequest) {
        Exam exam = examService.getById(examIdRequest.getExamId());
        exam.setStartTime(new Date(4070923200L * 1000));
        return ResultEntity.success("结束考试成功", examService.updateById(exam));
    }

    /**
     * 修改考试
     *
     * @param exam 考试实体对象
     * @return 结果实体类
     */
    @Transactional
    @PostMapping("/editOrUpdateExam")
    public ResultEntity editExam(@RequestBody @Valid Exam exam) {
        Paper paper = paperService.getById(exam.getPaperId());
        if (paper == null) {
            return ResultEntity.error("试卷不存在", null);
        }
        // 添加考试
        if (exam.getId() == -1) {
            exam.setId(null);
            examService.save(exam);
            return ResultEntity.success("添加考试成功", exam);
        }
        // 修改考试
        Exam exam1 = examService.getById(exam.getId());
        if (exam1 == null) {
            return ResultEntity.error("考试不存在", null);
        }
        // 如果试卷被修改，则删除改试卷的答题记录
        if (!exam1.getPaperId().equals(exam.getPaperId())) {
            examAnswerService.removeByExamId(exam1.getId());
        }
        examService.updateById(exam);
        return ResultEntity.success("修改考试成功", exam);
    }


    /**
     * 获取所有用户(分页)
     *
     * @param current 当前页数
     * @return 分页对象
     */
    @GetMapping("/getAllUser")
    public ResultEntity getAllUser(@RequestParam Integer current, @RequestParam String stuNumber) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        if (!stuNumber.equals("")) {
            userQueryWrapper.likeRight("stu_number", stuNumber);
        }
        Page<User> page = userService.page(new Page<>(current, 10), userQueryWrapper);
        return ResultEntity.success("获取用户成功", page);
    }

    /**
     * 获取用户
     *
     * @param userIdRequest 用户ID请求对象
     * @return 返回实体对象
     */
    @PostMapping("/getUser")
    public ResultEntity getUser(@RequestBody @Valid UserIdRequest userIdRequest) {
        User user = userService.getById(userIdRequest.getUserId());
        if (user == null) {
            return ResultEntity.error("用户不存在", null);
        }
        return ResultEntity.success("获取用户成功", user);
    }

    /**
     * 删除用户
     *
     * @param userIdRequest 用户ID请求对象
     * @return 返回实体对象
     */
    @PostMapping("/deleteUser")
    @Transactional
    public ResultEntity deleteUser(@RequestBody @Valid UserIdRequest userIdRequest) {
        Assert.isTrue(userService.removeById(userIdRequest.getUserId()), "删除用户失败");
        examStatusService.removeByUserId(userIdRequest.getUserId());
        examAnswerService.removeByUserId(userIdRequest.getUserId());
        return ResultEntity.success("删除用户成功", null);
    }

    /**
     * 重置用户密码
     *
     * @param userIdRequest 用户ID请求对象
     * @return 影响的行数
     */
    @PostMapping("/resetUserPass")
    public ResultEntity resetUserPass(@RequestBody @Valid UserIdRequest userIdRequest) {
        User user = userService.getById(userIdRequest.getUserId());
        if (user == null) {
            return ResultEntity.error("用户不存在", null);
        }
        user.setPassword("123456");
        return ResultEntity.success("重置密码成功", userService.updateById(user));
    }

    /**
     * 更新用户信息
     *
     * @param user 用户对象
     * @return 受影响的行数
     */
    @PostMapping("/editOrAddUser")
    public ResultEntity editOrAddUser(@RequestBody @Valid User user) {
        User user1;
        // 如果ID为-1则为创建
        if (user.getId() == -1) {
            user1 = userService.findByStuNumber(user.getStuNumber());
            if (user1 != null) {
                return ResultEntity.error("学号已存在", null);
            }
            user.setId(null);
            return ResultEntity.success("创建用户成功", userService.save(user));
        }
        // 判断用户
        user1 = userService.getById(user.getId());
        // 判断学号
        if (user1 == null) {
            return ResultEntity.error("用户不存在", null);
        }
        // 学号不一致
        if (!user1.getStuNumber().equals(user.getStuNumber())) {
            // 判断学号
            user1 = userService.findByStuNumber(user.getStuNumber());
            if (user1 != null) {
                return ResultEntity.error("学号已存在", null);
            }
        }
        // 最后把更新的对象传入
        return ResultEntity.success("更新用户成功", userService.updateById(user));
    }

    /**
     * 获取所有试卷（分页）
     *
     * @param current   当前页数
     * @param paperName 试卷名称
     * @return 分页实体
     */
    @GetMapping("/getAllPaper")
    public ResultEntity getAllPaper(@RequestParam Integer current, @RequestParam String paperName) {
        QueryWrapper<Paper> paperQueryWrapper = new QueryWrapper<>();
        if (!paperName.equals("")) {
            paperQueryWrapper.like("name", paperName);
        }
        Page<Paper> page = paperService.page(new Page<>(current, 10), paperQueryWrapper);
        return ResultEntity.success("获取试卷成功", page);
    }

    /**
     * 获取所有试卷(不分页，只有名称ID)
     *
     * @return 结果实体类
     */
    @GetMapping("/getAllPaperNoPage")
    public ResultEntity getAllPaperNoPage() {
        QueryWrapper<Paper> paperQueryWrapper = new QueryWrapper<>();
        paperQueryWrapper.orderBy(true, true, "id");
        paperQueryWrapper.select("id", "name");
        return ResultEntity.success("获取试卷成功", paperService.list(paperQueryWrapper));
    }

    /**
     * 删除试卷
     *
     * @param paperIdRequest 试卷ID请求对象
     * @return 结果实体类
     */
    @Transactional
    @PostMapping("/deletePaper")
    public ResultEntity deletePaper(@Valid @RequestBody PaperIdRequest paperIdRequest) {
        Paper paper = paperService.getById(paperIdRequest.getPaperId());
        if (paper == null) {
            return ResultEntity.error("试卷不存在", null);
        }
        // 开始删除
        Assert.isTrue(paperService.removeById(paperIdRequest.getPaperId()), "删除试卷失败");
        // 删除对应的用户答案
        examAnswerService.removeByPaperId(paperIdRequest.getPaperId());
        // 删除对应的考试状态
        examStatusService.removeByPaperId(paperIdRequest.getPaperId());
        // 删除对应的考试
        Wrapper<Exam> examWrapper = new UpdateWrapper<Exam>().eq("paper_id", paperIdRequest.getPaperId());
        examService.remove(examWrapper);
        return ResultEntity.success("删除试卷成功", null);
    }

    @PostMapping("/editOrAddPaper")
    public ResultEntity editOrAddPaper(@RequestBody @Valid Paper paper) {
        // 如果ID为-1则为创建
        if (paper.getId() == -1) {
            paper.setId(null);
            return ResultEntity.success("创建试卷成功", paperService.save(paper));
        }
        // 判断用户
        Paper paper1 = paperService.getById(paper.getId());
        if (paper1 == null) {
            return ResultEntity.error("试卷不存在", null);
        }
        // 最后把更新的对象传入
        return ResultEntity.success("更新试卷成功", paperService.updateById(paper));
    }

    /**
     * 获取试卷信息
     *
     * @param paperIdRequest 试卷ID请求对象
     * @return 结果实体类
     */
    @PostMapping("/getPaperInfo")
    public ResultEntity getPaperInfo(@RequestBody @Valid PaperIdRequest paperIdRequest) {
        Paper paper = paperService.getById(paperIdRequest.getPaperId());
        if (paper == null) {
            return ResultEntity.error("试卷不存在", null);
        }
        return ResultEntity.success("获取试卷信息成功", paper);
    }

    /**
     * 获取试卷题目
     *
     * @param paperIdRequest 试卷ID请求对象
     * @return 结果实体类
     */
    @PostMapping("/getPaperQuestion")
    public ResultEntity getPaperQuestion(@RequestBody @Valid PaperIdRequest paperIdRequest) {
        Wrapper<Question> questionWrapper = new QueryWrapper<Question>().eq("paper_id", paperIdRequest.getPaperId()).orderByAsc("type", "id");
        List<Question> list = questionService.list(questionWrapper);
        return ResultEntity.success("获取试卷题目成功", list);

    }

    /**
     * 获取题目详情
     *
     * @param questionId 题目ID
     * @return 结果实体类
     */
    @PostMapping("/getQuestion/{questionId}")
    public ResultEntity getQuestion(@PathVariable String questionId) {
        Question question = questionService.getById(questionId);
        if (question == null) {
            return ResultEntity.error("问题不存在", null);
        }
        return ResultEntity.success("获取问题成功", question);

    }

    /**
     * 编辑或增加题目
     *
     * @param editQuestionRequest 请求实体类
     * @return 受影响的行数
     * @throws JsonProcessingException JSON反序列化错误
     */
    @PostMapping("/editOrAddQuestion")
    public ResultEntity editOrAddQuestion(@Valid @RequestBody EditQuestionRequest editQuestionRequest) throws JsonProcessingException {
        Question question = new Question();
        question.setId(editQuestionRequest.getId());
        question.setPaperId(editQuestionRequest.getPaperId());
        question.setTitle(editQuestionRequest.getTitle());
        question.setContent(editQuestionRequest.getContent());
        question.setType(editQuestionRequest.getType());
        question.setScore(editQuestionRequest.getScore());
        question.setAnswer(objectMapper.writeValueAsString(editQuestionRequest.getAnswer()));
        question.setOptions(objectMapper.writeValueAsString(editQuestionRequest.getOptions()));
        // 判断试卷是否存在
        Paper paper = paperService.getById(question.getPaperId());
        if (paper == null) {
            return ResultEntity.error("试卷不存在", null);
        }
        if (question.getId() == -1) {
            // 添加问题
            return ResultEntity.success("添加题目成功", questionService.save(question));
        }
        // 判断问题是否存在
        Question sourceQuestion = questionService.getById(question.getId());
        if (sourceQuestion == null) {
            return ResultEntity.error("题目不存在", null);
        }
        return ResultEntity.success("修改题目成功", questionService.updateById(question));
    }

    /**
     * 删除问题
     *
     * @param questionId 问题ID
     * @return 结果实体类
     */
    @Transactional
    @PostMapping("/deleteQuestion/{questionId}")
    public ResultEntity deleteQuestion(@PathVariable String questionId) {
        Question question = questionService.getById(questionId);
        if (question == null) {
            return ResultEntity.error("题目不存在", null);
        }
        Assert.isTrue(questionService.removeById(questionId), "删除问题失败");
        Wrapper<ExamAnswer> wrapper = new UpdateWrapper<ExamAnswer>().eq("question_id", questionId);
        examAnswerService.remove(wrapper);
        return ResultEntity.success("删除问题成功", null);
    }

    @PostMapping("/getExamStatus")
    public ResultEntity getExamStatus(@RequestBody @Valid ExamIdRequest examIdRequest) {
        Exam exam = examService.getById(examIdRequest.getExamId());
        if (exam == null) {
            return ResultEntity.error("考试不存在", null);
        }
        List<Map<String, Object>> examStatus = examStatusService.getExamStatus(examIdRequest.getExamId());
        return ResultEntity.success("获取考试状态成功", examStatus);
    }

    @PostMapping("/submitExam")
    public ResultEntity submitExam(@RequestBody @Valid SubmitExamRequest submitExamRequest) {
        // 开始提交
        try {
            examStatusService.submitExam(submitExamRequest.getExamId(), submitExamRequest.getUserId());
        } catch (Exception e) {
            return ResultEntity.error(e.getMessage(), null);
        }
        return ResultEntity.success("强制交卷成功", null);
    }

    /**
     * 获取管理员用户
     *
     * @return 结果实体类
     */
    @GetMapping("/getAdminUser")
    public ResultEntity getAdminUser() {
        return ResultEntity.success("获取管理员用户成功", adminUserService.list());
    }
}
